# -*- coding: utf-8 -*-
import smtplib
import sys
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
from email.MIMEImage import MIMEImage
from email.MIMEBase import MIMEBase
from email.Encoders import encode_base64
import os
import mimetypes
import datetime
import re
import pymongo
from pymongo import Connection


### SEND MAIL ##################
def attachFile(attachmentPath):
    contentType, encoding = mimetypes.guess_type(attachmentPath)
    if contentType is None or encoding is None:
        contentType = "application/octet-stream"
    cType, subType = contentType.split("/", 1)
    
    file = open(attachmentPath, 'rb')
    if cType == 'image':
        attachment = MIMEImage(file.read(), _subtype=subType)
    else:
        attachment = MIMEBase('application', 'octet-stream')
        attachment.set_payload(file.read())
        encode_base64(attachment)
    attachment.add_header('Content-Disposition',
                    'attachment; filename="%s"' % os.path.basename(attachmentPath))
    return attachment
    
def mail(to, subject, body, attach=False, pathArr=None):
    msg = MIMEMultipart()
    global gmail_user, gmail_pwd
    msg['From'] = gmail_user[0]
    msg['To'] = to
    msg['Subject'] = subject

    msg.attach(MIMEText(body))
    if attach:
        for pathOfFile in pathArr:
            if os.path.isfile(pathOfFile):
                msg.attach(attachFile(pathOfFile))
    try:
        mailServer = smtplib.SMTP("smtp.gmail.com", 587)
    except:
        mailServer = smtplib.SMTP("smtp.gmail.com", 465)
    mailServer.ehlo()
    mailServer.starttls()
    mailServer.ehlo()
    mailServer.login(gmail_user[0], gmail_pwd[0])
    mailServer.sendmail(gmail_user, to, msg.as_string())
    mailServer.close()

def sendToMany(to, subject, body):
    for amail in to:
        mail(amail, subject, body)


############################################
def dbConnect(db="mongolog", col="log"):
    try:
        connection = Connection('localhost', 27017)
        db = connection[db]
        collection = db[col]
        collection.ensure_index("time", pymongo.DESCENDING)
        return collection
    except:
        print sys.exc_info()
        sys.exit()

def buildMessage(errType, data):
    msg = ''
    if len(data) < 1: return ''
    msg += "================================="
    msg += "\nTotal {0}: {1}".format(errType, len(data))
    for iLine in data:
        msg += iLine + "\n"
    msg += "\n\n"
    return msg

def sendReport(to):
    global collection, lastCheckedTime, maxNumberErrorEachEmail
    print lastCheckedTime
    try:
        criticalArr = []
        errorArr = []
        warningArr = []
        for row in collection.find({"level": {"$in": ['critical', 'error', 'warning']}, "time": {"$gte": lastCheckedTime}}).sort("time", pymongo.DESCENDING).limit(maxNumberErrorEachEmail):
            strErr = "\nTime: {0}\tName: {1}\tFunction: {2}\nMessage: {3}".format(row['time'], row['name'], row['funcname'], row['msg'])
            if row['level'] == 'critical':
                criticalArr.append(strErr)
            elif row['level'] == 'error':
                errorArr.append(strErr)
            else:
                warningArr.append(strErr)

        message = ""
        message += buildMessage('critical', criticalArr)
        message += buildMessage('error', errorArr)
        message += buildMessage('warning', warningArr)
        print message
        subject = "[Monitor] Mana monitoring report : {0}".format(str(datetime.datetime.now()))
        if message != '':
            sendToMany(to, subject, message)
    except:
        print sys.exc_info()
        raise

def writeFile(data, fileName, mode='w'):
    try:
        if not os.path.isfile(fileName):
            if not os.path.exists(os.path.dirname(fileName)):
                os.makedirs(os.path.dirname(fileName))
            f = file(fileName, 'w')
        else:
            f = open(fileName, mode)
        f.write(data)
        f.close()
    except:
        print sys.exc_info()
        pass

def standardizeTime():
    global file_config
    NOW = datetime.datetime.now()
    startOfDay = datetime.datetime(NOW.year, NOW.month, NOW.day)
    # -- create directory if not exist
    try:
        if not os.path.isfile(file_config):
            if not os.path.exists(os.path.dirname(file_config)):
                os.makedirs(os.path.dirname(file_config), 777)
            f = file(file_config, 'w')
            f.close()
    except:
        pass
    f = open(file_config, 'r')
    timeStr = f.readline().strip()
    f.close()    
    if re.search(r"\d+-\d+-\d+\s\d+:\d+:\d+\.\d+", timeStr):
        return datetime.datetime.strptime(timeStr, "%Y-%m-%d %H:%M:%S.%f")
    return startOfDay
    

########################## MAIN ################################

### GMAIL USER FOR SEND MAIL ###
gmail_user = ["monitor@mana.vn", "mana.notification@gmail.com"]
gmail_pwd = ["@monitor$", "@mana^^log**??"]
################################

toMail = ["giangnh@mana.vn"]
maxNumberErrorEachEmail = 50
file_config = "/home/hoangnamhai/send-mail-report-config.txt"
collection = dbConnect()
lastCheckedTime = standardizeTime()
sendReport(toMail)

writeFile(str(datetime.datetime.now()), file_config)

print "==== FINISHED ====", str(datetime.datetime.now())
os._exit(1)
